package it.koutifaris.travianmap.ui.animation;

public class Animator {

	private final Scheduler scheduler;
	private final Animation animation;
	private Step step;
	private boolean stop;
	private static final int NANO_TO_MILLIS_FACTOR = 1000000;

	public Animator(Scheduler scheduler, Animation animation) {
		this.scheduler = scheduler;
		this.animation = animation;
	}

	public void start() {
		animation.init();
		stop = false;
		step = new Step();
		step.start();
	}

	public void stop() {
		stop = true;
	}

	private class Step implements Runnable {

		private long start;
		private long updateTime;

		public void start() {
			start = now();
			updateTime = start;
			scheduler.scheduleNow(this);
		}

		@Override
		public void run() {
			long now = now();
			long ellapsedUpdateTime = now - updateTime;
			int updateRate = animation.getUpdateRate();

			if (ellapsedUpdateTime >= updateRate) {
				animation.update(now - start, ellapsedUpdateTime);
				updateTime = now;
			}

			if (animation.isRunning() && !stop) {
				float alpha = (float) (now - updateTime) / updateRate;
				animation.paint(alpha);
				scheduleNext();
			} else if (stop) {
				long stopTime = now();
				animation.stopped(stopTime - start, stopTime - now);
			}
		}

		private long now() {
			return System.nanoTime() / NANO_TO_MILLIS_FACTOR;
		}

		private void scheduleNext() {
			scheduler.scheduleDelayed(this, 1);
		}

	}
}
